package com.eversec.controller;

import com.eversec.dao.FeatureRepository;
import com.eversec.domain.FeatureModel;
import com.eversec.util.DateUtil;
import com.eversec.util.ResponseUtils;
import com.eversec.util.StringUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.jboss.logging.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.List;

import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
import static org.springframework.data.mongodb.core.query.Criteria.where;

/**
 * Created by eversec on 2017/7/10.
 */
@Api(value = "特征库md5上报发生频次",produces= MediaType.APPLICATION_JSON_VALUE)
@RequestMapping("/featureapi/*")
@RestController
public class FeatureController {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private FeatureRepository repository ;

    private static Logger logger = Logger.getLogger(FeatureController.class);

    @ApiOperation("特征库发生频次上报")
    @RequestMapping(path="/insert", method= RequestMethod.POST)
    public void save(HttpServletRequest request,
                       HttpServletResponse response,
                       @ApiParam(value = "md5") @RequestParam(required = true) String md5,
                       @ApiParam(value = "发生频次") @RequestParam(required = true) String frequency,
                       @ApiParam(value = "上报时间") @RequestParam(required = true) String reporttime){


        FeatureModel  model = new FeatureModel(md5.toLowerCase(),Integer.parseInt(frequency),DateUtil.getStrToDate(reporttime));
        repository.insert(model);

        ResponseUtils.dealResult(model, response);

    }



    @ApiOperation("查询所有特征库发生频次上报记录")
    @RequestMapping(path="/findAll", method= RequestMethod.GET)
    public void find(HttpServletRequest request,
                                   HttpServletResponse response){
        List<FeatureModel> list = repository.findAll();
        logger.info("************findAll()***************"+list.get(0).getReporttime());
        ResponseUtils.dealResult(list, response);

    }

    @ApiOperation("分页查询所有特征库发生频次上报记录")
    @RequestMapping(path="/findByPage", method= RequestMethod.POST)
    public  void  findByPage(HttpServletRequest request,
                                           HttpServletResponse response,
                                           @ApiParam(value = "1升序-1降序") @RequestParam(required = false ,defaultValue = "-1")  String sort,
                                           @ApiParam(value = "排序字段") @RequestParam(required = false ,defaultValue = "reporttime") String filed,
                                           @ApiParam(value = "页号") @RequestParam(required = true ,defaultValue = "1") String pageNum,
                                           @ApiParam(value = "每页记录") @RequestParam(required = true ,defaultValue = "1000") String pageSize){

        Sort  s =  new Sort("1".equals(sort)?Sort.Direction.ASC:Sort.Direction.DESC,filed);
        Pageable pageable = new PageRequest(Integer.parseInt(pageNum),Integer.parseInt(pageSize), s);
        Page<FeatureModel> modelPage = repository.findAll(pageable);
        ResponseUtils.dealResult(modelPage, response);

    }



    @ApiOperation("根据md5值查询特征库发生频次上报记录")
    @RequestMapping(path="/findByMd5", method= RequestMethod.POST)
    public void  findByMd5(HttpServletRequest request,
                                  HttpServletResponse response,
                                  @ApiParam(value = "md5") @RequestParam(required = true )  String md5){

        List<FeatureModel> list = repository.findByMd5(md5.toLowerCase());
        ResponseUtils.dealResult(list, response);

    }


    @ApiOperation("根据id查询特征库发生频次上报记录")
    @RequestMapping(path="/findById", method= RequestMethod.POST)
    public void findById(HttpServletRequest request,
                                        HttpServletResponse response,
                                        @ApiParam(value = "id") @RequestParam(required = true )  String id){

        FeatureModel model = repository.findOne(id);
        ResponseUtils.dealResult(model, response);

    }

    @ApiOperation("根据md5值删除记录")
    @RequestMapping(path="/delete", method= RequestMethod.POST)
    public void delete(HttpServletRequest request,
                         HttpServletResponse response,
                         @ApiParam(value = "md5") @RequestParam(required = true )  String md5){

        List<FeatureModel>  deletes =  repository.findByMd5(md5.toLowerCase());
        for (FeatureModel model:deletes) {

            repository.delete(model.getId());
        }

        ResponseUtils.dealResult(deletes, response);

    }

    @ApiOperation("根据id更新记录")
    @RequestMapping(path="/update", method= RequestMethod.POST)
    public void update(HttpServletRequest request,
                         HttpServletResponse response,
                         @ApiParam(value = "id") @RequestParam(required = true) String id,
                         @ApiParam(value = "md5") @RequestParam(required = true) String md5,
                         @ApiParam(value = "发生频次") @RequestParam(required = true) String frequency,
                         @ApiParam(value = "上报时间") @RequestParam(required = true) String reporttime){

            FeatureModel model = repository.findOne(id);
            if (model == null){
                model = new FeatureModel(md5.toLowerCase(),Integer.parseInt(frequency),DateUtil.getStrToDate(reporttime));
                repository.insert(model);
                logger.info("****************insert(model)*******************"+model.toString());
            }else{

                model.setFrequency(Integer.parseInt(frequency));
                model.setMd5(md5.toLowerCase());
                model.setReporttime(DateUtil.getStrToDate(reporttime));
                repository.save(model);
            }

         ResponseUtils.dealResult(model, response);

    }


    @ApiOperation("根据参数统计特征发生频次")
    @RequestMapping(path="/getSumFrequencyByParams", method= RequestMethod.POST)
    public void getSumFrequencyByParams(HttpServletRequest request,
                                                      HttpServletResponse response,
                                                      @ApiParam(value = "md5") @RequestParam(required = false) String md5,
                                                      @ApiParam(value = "发生频次>=") @RequestParam(required = false ,defaultValue = "0") String begin,
                                                      @ApiParam(value = "发生频次<=") @RequestParam(required = false ,defaultValue = "1000000") String end,
                                                      @ApiParam(value = "上报开始时间") @RequestParam(required = false ,defaultValue = "1990-01-01 00:00:00") String starttime,
                                                      @ApiParam(value = "上报结束时间") @RequestParam(required = false ,defaultValue = "2999-12-31 59:59:59") String endtime,
                                                      @ApiParam(value = "limit") @RequestParam(required = false ,defaultValue = "100") String limit,
                                                      @ApiParam(value = "1升序-1降序") @RequestParam(required = false ,defaultValue = "-1") String sort) {

        Aggregation aggregation = null ;
        //
        Date time1 = DateUtil.getStrToDate(starttime);
        Date time2 = DateUtil.getStrToDate(endtime);
        int num1 = Integer.parseInt(begin);
        int num2 = Integer.parseInt(end);
        int num3 = Integer.parseInt(limit);

        logger.info("**********上报开始时间: "+time1+"******上报结束时间: "+time2+"*******发生频次>=: "+num1+"*******发生频次<=: "+num2+"*******limit：*******"+num3);
        if(StringUtil.isValid(md5)){

            String [] md5s  =md5.toLowerCase().split(",");
            logger.info("****************insert(model)*******************"+md5s.toString());
            aggregation = newAggregation(
                    match(where("md5").in((Object) md5s)
                            .and("frequency").gte(num1)
                            .andOperator(where("reporttime").gte(time1),
                                    where("reporttime").lte(time2))),
                    group("md5")//设置分组字段
                            .sum("frequency").as("frequency"),
                    project("md5","frequency")
                            .and("md5").previousOperation(),//为前一操作所产生的ID FIELD建立别名
                    sort("-1".equals(sort)?Sort.Direction.DESC:Sort.Direction.ASC,"frequency"),
                    limit(num3)
            );
        }else{
            aggregation = newAggregation(
                    match(where("frequency").gte(num1)
                            .andOperator(where("reporttime").gte(time1),
                                    where("reporttime").lte(time2))),
                    group("md5")//设置分组字段
                            .sum("frequency").as("frequency"),
                    project("md5","frequency")
                            .and("md5").previousOperation(),//为前一操作所产生的ID FIELD建立别名
                    sort("-1".equals(sort)?Sort.Direction.DESC:Sort.Direction.ASC,"frequency"),
                    limit(num3)
            );

        }

        AggregationResults<FeatureModel> results = mongoTemplate.aggregate(aggregation, mongoTemplate.getCollectionName(FeatureModel.class), FeatureModel.class);

        ResponseUtils.dealResult(results.getMappedResults(), response);
    }


/*    @RequestMapping("getFrequencyByMd5")
    public List<FeatureModel> getFrequencyByMd5(List<String> importantCat1List) {

        logger.info(new Date().toString());

        mongoTemplate.getCollectionName(FeatureModel.class);

        *//**
         * db.videos.aggregate(
         [
         { $match: { "frags.isnew" : true } },
         { $unwind: "$frags" },
         { $match: { "frags.isnew" : true } },
         { $group: {
         _id: {cat1:"$cat1"},
         count: { $sum: 1 },
         publishdate2: { $max: "$publishdate"}
         }
         }

         ]
         )
         *//*
        Aggregation agg = newAggregation(
                project("frags","cat1","publishdate"),//挑选所需的字段
                match(
                        Criteria.where("frags.isnew").is(Boolean.TRUE)
                                .and("cat1").in(importantCat1List)
                ),//筛选符合条件的记录
                unwind("frags"),//如果有MASTER-ITEM关系的表，需同时JOIN这两张表的，展开子项LIST，且是内链接，即如果父和子的关联ID没有的就不会输出
                match(Criteria.where("frags.isnew").is(Boolean.TRUE)),
                group("cat1")//设置分组字段
                        .count().as("updateCount")//增加COUNT为分组后输出的字段
                        .last("publishdate").as("publishDate"),//增加publishDate为分组后输出的字段
                project("publishDate","cat1","updateCount")//重新挑选字段
                        .and("cat1").previousOperation()//为前一操作所产生的ID FIELD建立别名
        );


        AggregationResults<FeatureModel> results = mongoTemplate.aggregate(agg, Video.COLLECTION_NAME, FeatureModel.class);
        List<FeatureModel> list = results.getMappedResults();

        return list;
    }*/


}
